package com.fbty.mt.service.impl;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;

import com.fbty.base.dao.MtJdbcDao;
import com.fbty.base.domain.Page;
import com.fbty.mt.dao.ErrorIpInfoDao;
import com.fbty.mt.dao.IpInfoDao;
import com.fbty.mt.dao.OnlyIpInfoDao;
import com.fbty.mt.dao.RecordDao;
import com.fbty.mt.dao.UserDao;
import com.fbty.mt.dao.UserIpInfoDao;
import com.fbty.mt.domain.CheckInfo;
import com.fbty.mt.domain.ErrorIpInfo;
import com.fbty.mt.domain.IpInfo;
import com.fbty.mt.domain.OnlyIpInfo;
import com.fbty.mt.domain.Record;
import com.fbty.mt.domain.User;
import com.fbty.mt.domain.UserIpInfo;
import com.fbty.mt.service.IpService;
import com.fbty.mt.service.ProxyService;
import com.fbty.mt.utils.DateTool;
import com.fbty.mt.utils.IPInfoHelper;
/**
 * 用户登陆服务类
 * @author thinkpad
 *
 */
public class IpServiceImpl implements IpService{
	private MtJdbcDao mtJdbcDao;
	private IpInfoDao ipInfoDao;
	private OnlyIpInfoDao onlyIpInfoDao;
	private ErrorIpInfoDao errorIpInfoDao;
	private RecordDao recordDao;
	private UserDao userDao;
	private ProxyService proxyService;
	private UserIpInfoDao userIpInfoDao;
	/**
	 * 保存共享类ip
	 * @param ipInfo
	 */
	@Override
	public void saveIpInfo(IpInfo ipInfo) {
		ipInfoDao.save(ipInfo);
		
	}
	/**
	 * 保存共享类ip
	 * @param ipInfo
	 */
	@Override
	public void saveIpInfos(List<IpInfo> ipInfos) {
		ipInfoDao.saveAll(ipInfos);
		
	}
	/**
	 * 保存独享类ip
	 * @param ipInfo
	 */
	@Override
	public void saveOnlyIpInfos(List<OnlyIpInfo> ipInfos) {
		onlyIpInfoDao.saveAll(ipInfos);
	}

	/**
	 * 分页显示独享类ip
	 * @param ipInfo
	 */
	@Override
	public Page pageOnlyIpInsoes(Integer pageNo, Integer pageSize,
			boolean flag, Map<String, Object> parms) {
		
		if(flag) {
			String sql = " SELECT * FROM tab_only_ip_info ti WHERE ti.entranceIp IN(SELECT t.entranceIp FROM tab_only_ip_info t GROUP BY t.entranceIp having count(t.id) > 1 ) order by ti.entranceIp";
			List list = mtJdbcDao.getJdbcTemplate().queryForList(sql);
			return new Page(list, (pageNo-1)*pageSize, list.size(), pageSize);
		} else {
			String hql = "from OnlyIpInfo where type like :type and country like :country  and region like :region  and city like :city order by uploadTime desc ";
			return ipInfoDao.pagedQuery(hql, (pageNo-1), pageSize, parms);
		}
	}
	
	/**
	 * 分页显示共享类ip
	 * @param ipInfo
	 */
	@Override
	public Page pageIpInsos(Integer pageNo, Integer pageSize,boolean flag,Map<String,String> parms) {
		if(flag) {
			String sql = " SELECT * FROM tab_ip_info ti GROUP BY ti.ip,ti.port HAVING COUNT(ti.ip) >1 order by ti.ip";
			List list = mtJdbcDao.getJdbcTemplate().queryForList(sql);
			//Integer count = mtJdbcDao.getJdbcTemplate().queryForInt(sqlCount);
			return new Page(list, (pageNo-1)*pageSize, list.size(), pageSize);
		} else {
			String hql = "from IpInfo where  state = :state and type like :type and country like :country  and region like :region  and city like :city order by updateTime desc ";
			Page page = ipInfoDao.pagedQuery(hql, pageNo, pageSize, parms);
			return page;
			
		}
	}
	@Override
	public void saveErrorIpInfos(List<ErrorIpInfo> ipInfos) {
		errorIpInfoDao.saveAll(ipInfos);
	}
	/**
	 * 一次取出共享类ip
	 * @param ipInfo
	 */
	public List<IpInfo> getAllIpInfoes() {
		String hql = " from IpInfo where state<3 ";
		return ipInfoDao.find(hql);
	}
	/**
	 * 分页显示我的代理
	 * @param pageNo
	 * @param parms
	 * @return
	 */
	public Page pageMyIpInfos(Integer pageNo,Integer pageSize,Map parms)  {
		String hql = " select tr,ti from IpInfo ti,IpRecord tr where ti.id= tr.pid and " +
					 " tr.state!=3 and tr.uid=:uid and type like :type and state like :state " +
					 " and buyDate between :startDate and :endDate order by tr.id desc ";
		Page page =  ipInfoDao.pagedQuery(hql,pageNo*pageSize, pageSize,parms);
		
		List<Object[]> list = page.getResult();
		List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
		for(int i=0;i<list.size();i++){
			Map<String, Object> map = new HashMap<String,Object>();
			for(Object obj:list.get(i)){
				if(obj instanceof IpInfo){
					IpInfo info = (IpInfo)obj;
					map.put("ip", info.getIp());
					map.put("port", info.getPort());
					map.put("country", info.getCountry());
					map.put("region", info.getRegion());
					map.put("city", info.getCity());
					map.put("type", info.getType());
				}
				if(obj instanceof Record){
					Record ipRecord = (Record)obj;
					map.put("id", ipRecord.getId());
					map.put("buyDate",DateTool.parseDateToString(ipRecord.getBuyDate()));
				}
			}
			result.add(map);
		}
		page.setResult(result);
		return page;
	}
	/**
	 * 批量删除用户已代理的ip
	 * @param params
	 */
	public void deleteForMyIp(final int[] cid) {
		String sql = " update tab_record set state=3 where id =? ";
		int ipInfo[] =mtJdbcDao.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				ps.setInt(1, cid[i]);
			}
			
			@Override
			public int getBatchSize() {
				return cid.length;
			}
		});
	}
	/**
	 * 得到包月用户这个在有效时间内还有多少条可以用
	 * @return
	 */
	public String getMsg(Integer uid) {
		String sql = " select id from tab_record where state=1 and uid="+uid;
		List list = mtJdbcDao.getJdbcTemplate().queryForList(sql);
		return " | 本月您已购买了<span style='color:red'>"+list.size()+"</span>条,还剩下<span style='color:green'>"+(300-list.size())+"</span>";
	}
	/**
	 * 批量删除共享类ip
	 * @param ids
	 */
	@Override
	public void deleteInfo(String ids) {
		String recordsql = " delete from  tab_record where pid in ("+ids+") ";
		String ipInfosql = " delete from  tab_ip_info where id in ("+ids+")";
		mtJdbcDao.getJdbcTemplate().execute(recordsql);
		mtJdbcDao.getJdbcTemplate().execute(ipInfosql);
		/*String recordsql = " delete from  tab_record where pid = ? ";
		String ipInfosql = " delete from  tab_ip_info where id = ? ";
		int ipInfo[] =mtJdbcDao.getJdbcTemplate().batchUpdate(ipInfosql, new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				ps.setInt(1, cid[i]);
			}
			
			@Override
			public int getBatchSize() {
				return cid.length;
			}
		});
		int record[] =mtJdbcDao.getJdbcTemplate().batchUpdate(recordsql, new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				ps.setInt(1, cid[i]);
			}
			
			@Override
			public int getBatchSize() {
				return cid.length;
			}
		});*/
	}
	/**
	 * 批量删除独享类ip
	 * @param ids
	 */
	@Override
	public void removeOnlyInfo(String ids) {
//		String recordsql = " delete from  tab_record where pid in ("+ids+") ";
//		mtJdbcDao.getJdbcTemplate().execute(recordsql);
		String ipInfosql = " delete from  tab_only_ip_info where id in ("+ids+")";
		mtJdbcDao.getJdbcTemplate().execute(ipInfosql);
	}
	/**
	 * 批量删除独享类ip
	 * @param ids
	 */
	@Override
	public void deleteOnlyInfo(final int[] cid) {
		String ipInfosql = " delete from  tab_ip_info where id = ? ";
		
		int ipInfo[] =mtJdbcDao.getJdbcTemplate().batchUpdate(ipInfosql, new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				ps.setInt(1, cid[i]);
			}
			
			@Override
			public int getBatchSize() {
				return cid.length;
			}
		});
	}
	/**
	 * 批量提取ip
	 */
	public Map<String, Integer> saveManyBuy(Integer buynum,User user) {
		/**
		 * 拿到当前用户已经购买的Ip
		 */
		String hql = " from UserIpInfo where uid=? ";
		List<UserIpInfo> records = userIpInfoDao.find(hql,user.getId());
		StringBuilder sb = new StringBuilder();
		for(UserIpInfo record : records) {
			sb.append(record.getIpid()+",");
		}
		sb.append("0");
		String sql = " select id from tab_ip_info where id not in ("+sb+")";
		//得到不重复ip
		List<Map<String, Object>> list = mtJdbcDao.getJdbcTemplate().queryForList(sql);
		
		Map<String, Integer> map = new HashMap<String, Integer>();
		if(list.size() == 0) { //说明用户的已经买过了所有的ip
			map.put("monthnum", user.getMonthnum());
			map.put("num", user.getNum());
			map.put("buy", 0);
			return map;
		}
		/**
		 * 存入数据库
		 */
		Integer len = 0;
		if(buynum > list.size()) { //如果购买数量大于不重复ip的数量
			len = list.size();	
		} else {
			len = buynum;
		}
		
		Integer monthNum = 0;
		if((user.getMonthnum() - len) < 0) { //如果getMonthnum不够，差多少用num来减
			monthNum = buynum-user.getMonthnum();//计算出差多少条
			user.setNum(user.getNum()-monthNum);
			user.setMonthnum(0);
		} else {
			user.setMonthnum(user.getMonthnum()-len);
		}
		
		List<UserIpInfo> list2 = new ArrayList<UserIpInfo>();
		
		for(int i=0; i<len; i++) {
			UserIpInfo info = new UserIpInfo();
			info.setEndTime(System.currentTimeMillis());
			info.setFlag(false);
			info.setIpid(Integer.parseInt(list.get(i).get("id")+""));
			info.setUid(user.getId());
			info.setAutoChange(false);
			info.setNum(0);
			list2.add(info);
		}
		userIpInfoDao.saveAll(list2);
		userDao.update(user);
		
		map.put("monthnum", user.getMonthnum());
		map.put("num", user.getNum());
		map.put("buy", len);
		return map;
	}
	public MtJdbcDao getMtJdbcDao() {
		return mtJdbcDao;
	}
	public void setMtJdbcDao(MtJdbcDao mtJdbcDao) {
		this.mtJdbcDao = mtJdbcDao;
	}
	public IpInfoDao getIpInfoDao() {
		return ipInfoDao;
	}
	public void setIpInfoDao(IpInfoDao ipInfoDao) {
		this.ipInfoDao = ipInfoDao;
	}
	public OnlyIpInfoDao getOnlyIpInfoDao() {
		return onlyIpInfoDao;
	}
	public void setOnlyIpInfoDao(OnlyIpInfoDao onlyIpInfoDao) {
		this.onlyIpInfoDao = onlyIpInfoDao;
	}
	@Override
	public Page pageOnlyIpInfos(Integer pageNo, Integer pageSize, boolean flag,
			Map<String, Object> parms) {
		if(flag) {
			String sql = " SELECT * FROM tab_only_ip_info  WHERE ip IN(SELECT t.ip FROM tab_only_ip_info t GROUP BY t.ip having count(t.id) > 1 ) ";
			List list = mtJdbcDao.getJdbcTemplate().queryForList(sql);
			return new Page(list, pageNo*pageSize, list.size(), pageSize);
		} else {
			String hql = "from OnlyIpInfo where type like :type and country like :country  and region like :region and state=0 and used=:used and city like :city order by id ";
			return ipInfoDao.pagedQuery(hql, pageNo, pageSize, parms);
		}
	}

	
	/**
	 * 
	 * Description: 获取延迟<br>
	 * @param line
	 */
	private  IpInfo  updateIp(IpInfo info){
			System.out.println("afterInfo:"+info);
			Integer  type = 0;
			if("socks5".equalsIgnoreCase(info.getType())) {
				type = CheckInfo.SOCKS5_PROXY;
			} else if("socks4".equalsIgnoreCase(info.getType())) {
				type = CheckInfo.SOCKS4_PROXY;
			} else if("http".equalsIgnoreCase(info.getType())) {
				type = CheckInfo.HTTP_PROXY;
			} else if("https".equalsIgnoreCase(info.getType())) {
				type = CheckInfo.HTTPS_PROXY;
			}
			IPInfoHelper.getIPInfo(info.getIp());
			CheckInfo checkInfo = proxyService.checkConnection(info.getIp(), Integer.parseInt(info.getPort()), type);
			if(checkInfo.getReslut() == 0) {
				info.setSpeed(checkInfo.getDelay()+"");
				Map<String, String> map = IPInfoHelper.getIPInfo(info.getIp());
				info.setCity(map.get("City")==null?"--":map.get("City"));
				info.setCountry(map.get("Country")==null?"--":map.get("Country"));
				info.setRegion(map.get("Region")==null?"--":map.get("Region"));
				info.setUpdateTime(new Date());
				return info;
			}
			return null;
	}
	
	@Override
	public List<OnlyIpInfo> buyBatch(List<String> ids) {
		
		StringBuilder sb = new StringBuilder();
		
		for(int i=0;i<ids.size();i++){
			if(i==0){
				sb.append(ids.get(i));
			}
			sb.append(","+ids.get(i));
		}
		
		String hql = "from OnlyIpInfo where id in ("+sb+")";
		return onlyIpInfoDao.find(hql);
	}
	
	public ErrorIpInfoDao getErrorIpInfoDao() {
		return errorIpInfoDao;
	}
	public void setErrorIpInfoDao(ErrorIpInfoDao errorIpInfoDao) {
		this.errorIpInfoDao = errorIpInfoDao;
	}
	@Override
	public OnlyIpInfo findOnlyById(int id) throws Exception {
		
		return onlyIpInfoDao.get(id);
	}
	@Override
	public void updateOnlyIp(OnlyIpInfo onlyIp) throws Exception {
		onlyIpInfoDao.update(onlyIp);
	}
	@Override
	public void saveOnlyIpInfo(OnlyIpInfo onlyIpInfo) {
		onlyIpInfoDao.save(onlyIpInfo);
	}
	public RecordDao getRecordDao() {
		return recordDao;
	}
	public void setRecordDao(RecordDao recordDao) {
		this.recordDao = recordDao;
	}
	public UserDao getUserDao() {
		return userDao;
	}
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	public ProxyService getProxyService() {
		return proxyService;
	}
	public void setProxyService(ProxyService proxyService) {
		this.proxyService = proxyService;
	}
	@Override
	public IpInfo findIpInfoById(Integer id) {
		
		return ipInfoDao.get(id);
	}
	@Override
	public void modifyIpInfo(IpInfo info) {
		ipInfoDao.update(info);
	}
	@Override
	public OnlyIpInfo findOnlyIpInfoById(Integer id) {
		return onlyIpInfoDao.get(id);
	}
	@Override
	public void modifyIpInfo(OnlyIpInfo info) {
		onlyIpInfoDao.update(info);
	}
	public UserIpInfoDao getUserIpInfoDao() {
		return userIpInfoDao;
	}
	public void setUserIpInfoDao(UserIpInfoDao userIpInfoDao) {
		this.userIpInfoDao = userIpInfoDao;
	}


}
